import type { FetchPrams } from '@minmetals-ui/template';
import type Node from 'element-plus-cisdi/es/components/tree/src/model/node';
import type {
  AssignUserParam,
  ColumnDialogProps,
  DataTypes,
  DefaultRow,
  DeleteResponse,
  PageCommonSchema,
  RecordType,
  RoleData,
  RoleRecord,
  SelectItem,
  UserAssignment,
  UserRecord,
} from '../types/QueryCondition';
import { ElMessage } from 'element-plus-cisdi';
import { cloneDeep, isNaN } from 'lodash-es';
import { computed, reactive, ref, watch } from 'vue';
import { useI18n } from 'vue-i18n';
import { RoleService } from '@/services/RoleManageService';
import { UserService } from '@/services/UserService';

export function useSystemAdministrator() {
  const { t } = useI18n();
  const isCurrentLevel = ref(false);
  const addUserDialogVisible = ref(false);
  const inheritList = ref<SelectItem[]>([]);
  const treeTableRef = ref<any>(null);
  const assignDialogRef = ref<any>(null);
  const selectedValue = ref<DataTypes[]>([]);
  const currentNodeKey = ref('');
  const assignDialogVisible = ref(false);
  const assignModelValue = reactive<RecordType>({});
  const assignRowData = ref<Array<UserRecord>>([]);
  const dialogVisible = ref(false);
  const dialogFormValue = ref<ColumnDialogProps['modelValue']>({
    roleCode: '',
    roleName: '',
    description: '',
    inheritedRoleId: '',
    subVisible: 1,
    status: 1,
    remark: '',
  });
  const isFirst = ref(true);
  const firstOrg = ref('');
  const orgCode = ref('');
  const firstOrgLabel = ref('');
  const dialogMode = ref<'add' | 'edit'>('add');
  const dialogDisabled = ref(false);
  // 授权用户分页信息
  const assignRolesPageInfo = reactive({
    current: 1,
    size: 10,
    total: 0,
  });
  const defaultExpandedKeys = ref<string[]>();
  const firstLoad = ref(true);
  const column = computed(() => {
    return [{
      label: t('roleManage.columnList.roleCode'),
      prop: 'roleCode',
      width: '120',
      editProps: {
        isEditingDisabled: true,
        fieldComponent: 'Input',
        fieldProps: {
          placeholder: t('roleManage.placeholder.roleCode'),
        },
        fieldItemProps: {
          labelCol: 8,
          wrapperCol: 16,
        },
        fieldValidator: {
          required: true,
        },
      },
    }, {
      label: t('roleManage.columnList.roleName'),
      prop: 'roleName',
      width: '120',
      editProps: {
        fieldComponent: 'Input',
        isEditingDisabled: !isCurrentLevel.value,
        isCreatingDisabled: false,
        fieldProps: {
          placeholder: t('roleManage.placeholder.roleName'),
        },
        fieldItemProps: {
          labelCol: 8,
          wrapperCol: 16,
        },
        fieldValidator: {
          required: true,
        },
      },
    }, {
      label: t('roleManage.columnList.roleDesc'),
      prop: 'description',
      width: '200',
      editProps: {
        fieldComponent: 'Input',
        isEditingDisabled: !isCurrentLevel.value,
        fieldProps: {
          placeholder: t('roleManage.placeholder.roleDesc'),
          type: 'textarea',
          maxlength: 200,
          showWordLimit: true,
        },
        fieldItemProps: {
          labelCol: 8,
          wrapperCol: 16,
        },
        fieldValidator: {
          required: false,
        },
      },
    }, {
      label: t('roleManage.columnList.scope'),
      prop: 'orgLevel',
      width: '80',
    }, {
      label: t('roleManage.columnList.parentRole'),
      prop: 'inheritedRoleId',
      width: '180',
      // showOverflowTooltip: false,
      editProps: {
        fieldComponent: 'Select',
        isEditingDisabled: !isCurrentLevel.value,
        fieldProps: {
          options: inheritList.value,
          filterable: true,
        },
        fieldItemProps: {
          labelCol: 8,
          wrapperCol: 16,
        },
        fieldValidator: {
          required: false,
        },
      },
    }, {
      label: t('roleManage.columnList.subVisible'),
      prop: 'subVisible',
      width: '80',
      editProps: {
        fieldComponent: 'Switch',
        fieldProps: {
          activeValue: 1,
          inactiveValue: 0,
          // tooltip: '开启后，系统将在后台自动下载并安装更新，无需手动操作。',
        },
        fieldItemProps: {
          labelCol: 8,
          wrapperCol: 16,
        },
        defaultValue: 1,
        fieldValidator: {
          required: false,
        },
      },
    }, {
      label: t('roleManage.columnList.status'),
      prop: 'status',
      width: '80',
      editProps: {
        fieldComponent: 'Radio',
        isEditingDisabled: !isCurrentLevel.value,
        fieldProps: {
          options: [
            { label: t('roleManage.status.enable'), value: 1 },
            { label: t('roleManage.status.disable'), value: 0 },
          ],
        },
        fieldItemProps: {
          labelCol: 8,
          wrapperCol: 16,
        },
        defaultValue: 1,
        isCreatingDisabled: false,
        fieldValidator: {
          required: false,
        },
      },
    }, {
      label: t('roleManage.columnList.tip'),
      prop: 'remark',
      width: '200',
      editProps: {
        fieldComponent: 'Input',
        isEditingDisabled: !isCurrentLevel.value,
        fieldProps: {
          placeholder: t('roleManage.placeholder.remark'),
          type: 'textarea',
          maxlength: 200,
          showWordLimit: true,
        },
        fieldItemProps: {
          labelCol: 8,
          wrapperCol: 16,
          // gridSpan: 2,
        },
        fieldValidator: {
          required: false,
        },
      },
    }, {
      label: t('roleManage.columnList.createBy'),
      prop: 'createName',
      width: '120',
    }, {
      label: t('roleManage.columnList.createTime'),
      prop: 'createTime',
      width: '180',
    }, {
      label: t('roleManage.columnList.updateBy'),
      prop: 'updateName',
      width: '120',
    }, {
      label: t('roleManage.columnList.updateTime'),
      prop: 'updateTime',
      width: '180',
    }];
  });

  const editColumn = computed(() => {
    const editColumns: PageCommonSchema[] = [];
    column.value?.forEach((col) => {
      if (col.editProps) {
        const fieldProps = {
          ...(col.editProps?.fieldProps ?? {}),
          disabled: dialogMode.value === 'add' ? (col.editProps.isCreatingDisabled ?? false) : (col.editProps.isEditingDisabled ?? false),
        };
        const mergedEditProps = {
          ...col.editProps,
          fieldProps,
        };
        editColumns.push({ field: col.prop || '', fieldTitle: col.label, ...mergedEditProps });
      }
    });
    return editColumns;
  });

  const assignProps = computed(() => {
    return {
      title: t('roleManage.assign.title'),
      grid: {
        minColumns: 1,
        maxColumns: 2,
        labelCol: 6,
        wrapperCol: 18,
      },
      closeOnClickModal: false,
      queryCondition: [
        {
          field: 'roleCode',
          fieldTitle: t('roleManage.columnList.roleCode'),
          fieldComponent: 'Input',
          // mode: 'multiple',
          fieldProps: {
            placeholder: t('roleManage.placeholder.roleCode'),
            disabled: true,
          },
          defaultValue: assignModelValue.roleCode,
          fieldItemProps: {
            labelCol: 6,
            wrapperCol: 18,
          },
          fieldValidator: {
          },
        },
        {
          field: 'roleName',
          fieldTitle: t('roleManage.columnList.roleName'),
          fieldComponent: 'Input',
          mode: 'multiple',
          fieldProps: {
            placeholder: t('roleManage.placeholder.roleName'),
            disabled: true,
          },
          defaultValue: assignModelValue.roleName,
          fieldItemProps: {
            labelCol: 6,
            wrapperCol: 18,
          },
          fieldValidator: {
            // required: true,
          },
        },
        {
          field: 'description',
          fieldTitle: t('roleManage.columnList.roleDesc'),
          fieldComponent: 'Input',
          mode: 'multiple',
          fieldItemProps: {
            labelCol: 6,
            wrapperCol: 18,
            // gridSpan: 2,
          },
          fieldProps: {
            placeholder: t('roleManage.placeholder.roleDesc'),
            disabled: true,
            type: 'textarea',
            maxlength: 200,
            showWordLimit: true,
          },
          defaultValue: assignModelValue.description,
        },
      ],
      columnDialog: [
        {
          prop: 'userId',
          label: t('roleManage.assign.assignUserColumn.userCode'),
          type: 'input',
          required: true,
          width: 130,
          defaultValue: assignModelValue.userId,
        },
        {
          prop: 'userName',
          label: t('roleManage.assign.assignUserColumn.userName'),
          type: 'select',
          width: 130,
          defaultValue: assignModelValue.userName,
        },
        {
          prop: 'orgFullNamePath',
          label: t('roleManage.assign.assignUserColumn.orgName'),
          type: 'check',
          width: 280,
          defaultValue: assignModelValue.orgName,
        },
        {
          prop: 'createName',
          label: t('roleManage.assign.assignUserColumn.assignee'),
          type: 'check',
          width: 140,
          defaultValue: assignModelValue.createName,
        },
        {
          prop: 'createTime',
          label: t('roleManage.assign.assignUserColumn.assignTime'),
          type: 'check',
          width: 200,
          defaultValue: assignModelValue.createTime,
        },
      ],
    };
  });

  const dialogModeMap = {
    edit: t('roleManage.editRole'),
    add: t('roleManage.addRole'),
  };

  const dialogTitle = computed(() => dialogModeMap[dialogMode.value]);

  watch([() => assignRolesPageInfo.current, () => assignRolesPageInfo.size], () => {
    if (assignModelValue) {
      const data = {
        size: assignRolesPageInfo.size,
        current: assignRolesPageInfo.current,
        roleId: assignModelValue.roleId,
        search: assignDialogRef.value.inputValue || '',
        orgCode: currentNodeKey.value || firstOrg.value,
      };
      queryAssignUser(data);
    }
  }, { immediate: false, deep: false });

  function toNumber(value: string | number | undefined | null) {
    return isNaN(Number(value)) ? 0 : Number(value);
  }

  async function addActionClick() {
    dialogFormValue.value = { roleName: '', subVisible: 1, status: 1, remark: '', inheritedRoleId: '', description: '', roleCode: '' };
    const res = await RoleService.getInheritRoleList({ orgCode: currentNodeKey.value || firstOrg.value });
    const list: SelectItem[] = [];
    dialogVisible.value = true;
    dialogDisabled.value = false;
    dialogMode.value = 'add';
    res.data?.forEach((item: any) => {
      list.push({
        value: item?.roleId || '',
        label: item.roleOrgName && item.roleName ? `${item.roleOrgName}/${item.roleName}` : item.roleName || item.roleOrgName || '',
        data: {
          inheritedRoleOrgCode: item?.roleOrgCode || '',
          inheritedRoleOrgName: item?.roleOrgName || '',
          inheritedRoleId: item?.roleId || '',
          inheritedRoleName: item.roleName,
        },
      });
    });
    inheritList.value = list || [];
  }

  async function editColumnClick(record: DefaultRow) {
    const params = {
      orgCode: record.roleOrgCode,
      roleId: record.roleId,
    };
    const res = await RoleService.getInheritRoleList(params);
    const list: SelectItem[] = [];
    dialogVisible.value = true;
    dialogMode.value = 'edit';
    isCurrentLevel.value = record?.orgLevel !== 'HIGH';
    dialogDisabled.value = record?.orgLevel === 'HIGH';
    dialogFormValue.value = cloneDeep(record) as ColumnDialogProps['modelValue'];
    res.data?.forEach((item: any) => {
      list.push({
        value: item?.roleId || '',
        label: item.roleOrgName && item.roleName ? `${item.roleOrgName}/${item.roleName}` : item.roleName || item.roleOrgName || '',
        data: item,
      });
    });
    inheritList.value = list || [];
  }

  async function fetchData(params: FetchPrams) {
    const scope = params.scope === 'HIGH' ? '3' : (params.scope === 'CURRENT' ? '2' : '1');
    const fetchParam = {
      orgCode: isFirst.value ? firstOrg.value : params.code,
      scope: scope || '1',
      current: params.pageNum || 1,
      size: params.pageSize || 10,
      search: params.search || '',
    };
    const res = await RoleService.getRoleList(fetchParam);
    return {
      data: res.data.records,
      total: toNumber(res.data.total),
    };
  }

  async function createData(params: RoleRecord) {
    const { inheritedRoleId } = params || {};
    const index = inheritList.value.findIndex(item => item.data.inheritedRoleId === inheritedRoleId);
    const inheritData = index !== -1 ? inheritList.value[index].data : {};
    const data = {
      ...params,
      ...inheritData,
      orgCode: currentNodeKey.value || firstOrg.value,
    };
    const res: any = await RoleService.saveRoleData(data);
    if (res) {
      ElMessage.success(res.message);
      treeTableRef.value.loadData();
    } else {
      ElMessage.error(res.message);
    }
    return {
      data: {
        code: res.code,
        message: res.code,
      },
    };
  }

  async function queryAssignUser(params: AssignUserParam) {
    const res = await RoleService.getAssignUserList(params);
    assignRolesPageInfo.total = toNumber(res.data.total);
    assignRowData.value = res.data.records || [];

    selectedValue.value = res.data?.records.map((item: any) => ({
      orgCode: item.orgCode,
      userId: item.userId,
      label: item.userName,
      avatarUrl: item?.avatarUrl || null,
      fullNamePath: item?.orgFullNamePath || '',
    })) || [];
    return res;
  }

  async function assignUsersClick(data: RecordType) {
    const fetchData = {
      current: 1,
      size: 10,
      roleId: data.roleId,
      orgCode: currentNodeKey.value || firstOrg.value,
    };

    assignDialogVisible.value = true;
    Object.assign(assignModelValue, data);

    assignDialogVisible.value = true;
    Object.assign(assignModelValue, data);
    const res = await RoleService.getAssignUserList(fetchData);
    assignRolesPageInfo.total = toNumber(res.data.total);
    assignRowData.value = res.data.records || [];

    selectedValue.value = res.data?.records.map((item: any) => ({
      orgCode: item.orgCode,
      userId: item.userId,
      label: item.userName,
      avatarUrl: item?.avatarUrl || null,
      fullNamePath: item?.orgFullNamePath || '',
    })) || [];
  }

  function closeAssignDialog() {
    assignDialogVisible.value = false;
  }

  function saveDialogData(data: Array<RecordType>) {
    console.log('saveDialogData', data);
  }

  async function deleteUser(list: number[]) {
    if (!list.length) {
      ElMessage.warning(t('roleManage.placeholder.deleteSelect'));
      return;
    }
    const res = await RoleService.deleteAssignUser({ ids: list });
    if (res) {
      ElMessage.success(res.message);
      const fetchData = {
        current: 1,
        size: 10,
        roleId: assignModelValue.roleId,
        orgCode: currentNodeKey.value || firstOrg.value,
      };
      queryAssignUser(fetchData);
    }
  }

  function openAddAssignUser() {
    addUserDialogVisible.value = true;
    orgCode.value = currentNodeKey.value || firstOrg.value;
  }

  function closeAddUser() {
    addUserDialogVisible.value = false;
  }

  async function onAddUserOk(data: RecordType[]) {
    // const uniqueKeySet = new Set(selectedValue.value.map(item => `${item.orgCode}-${item.userId}`));
    const list: UserAssignment[] = [];
    data.forEach((item) => {
      // const itemUniqueKey = `${item.orgCode}-${item.userId}`;
      // if (!uniqueKeySet.has(itemUniqueKey)) {
      list.push({
        userId: item.userId,
        userName: item.label,
        orgCode: item.orgCode,
      });
      // }
    });
    if (list.length === 0) {
      closeAddUser();
      return;
    }
    const res: any = await RoleService.addAssignUser({
      users: list,
      roleId: assignModelValue.roleId,
      orgCode: currentNodeKey.value || firstOrg.value,
    });
    if (res) {
      ElMessage.success(t('userRole.addUserSuccess'));
      const fetchData = {
        current: 1,
        size: 10,
        roleId: assignModelValue.roleId,
        orgCode: currentNodeKey.value || firstOrg.value,
      };
      queryAssignUser(fetchData);
    } else {
      ElMessage.error(res.message);
    }
    closeAddUser();
  }

  async function queryOrgList(node?: Node, resolve?: (data: []) => void) {
    try {
      const res = await RoleService.queryOrgList({
        orgCode: node?.data?.code || 'root',
        isTree: '1',
        loadType: 0,
      });
      const list = res.data[node?.data?.code || 'root'] || [];
      if (isFirst.value) {
        if (firstLoad.value) {
          list.length > 0 && treeTableRef.value?.setActionTitle(list[0]?.label);
          treeTableRef.value?.searchTreeRef?.treeRef?.setCurrentKey?.(list[0]?.code);
          firstOrgLabel.value = list[0]?.label || '';
          firstLoad.value = false;
        }
        firstOrg.value = node?.data?.code
          ? node.data.code
          : list.length > 0
            ? list[0]?.code
            : null;
        if (node?.level === 0) {
          defaultExpandedKeys.value = [list[0]?.code];
        }
      }
      resolve?.(list);
    } catch (error) {
      console.log(error);
      resolve?.([]);
    }
    return Promise.resolve([]);
  }

  async function enableClick(params: RoleData[]) {
    if (params.length !== 0) {
      const list: RoleData[] = [];
      params.forEach((item) => {
        list.push({
          roleId: item.roleId,
          status: 1,
        });
      });
      const res = await RoleService.updateStatus({ data: list });
      if (res) {
        treeTableRef.value.loadData();
        ElMessage.success(res.message);
      }
    } else {
      ElMessage.warning(t('roleManage.placeholder.roleStatus'));
    }
  }

  async function disableClick(params: RoleData[]) {
    if (params.length !== 0) {
      const list: RoleData[] = [];
      params.forEach((item) => {
        list.push({
          roleId: item.roleId,
          status: 0,
        });
      });
      const res = await RoleService.updateStatus({ data: list });
      if (res) {
        treeTableRef.value.loadData();
        ElMessage.success(res.message);
      }
    } else {
      ElMessage.warning(t('roleManage.placeholder.roleStatus'));
    }
  }

  function handleNodeClick(data: any) {
    currentNodeKey.value = data.code;
    isFirst.value = false;
  }

  async function deleteRoleData(record: DefaultRow | DefaultRow[]): Promise<DeleteResponse> {
    const list = Array.isArray(record) ? record : [record];
    return await RoleService.deleteRoles({ roleIds: list.map(item => item.roleId) });
  }

  async function searchData(params: object) {
    const data = {
      orgCode: 'root',
      isTree: 0,
      loadType: 1,
      ...params,
    };
    return UserService.getOrgTreeOriginalData(data);
  }

  function treeClearSearchValue() {
    currentNodeKey.value = firstOrg.value;
    treeTableRef.value?.setActionTitle(firstOrgLabel.value);
    treeTableRef.value?.searchTreeRef?.treeRef?.setCurrentKey?.(firstOrg.value);
    treeTableRef.value.loadData({ code: firstOrg.value });
  }

  return {
    dialogDisabled,
    treeClearSearchValue,
    column,
    // rowData,
    fetchData,
    createData,
    assignUsersClick,
    currentNodeKey,
    assignModelValue,
    assignProps,
    assignDialogVisible,
    assignRowData,
    closeAssignDialog,
    saveDialogData,
    deleteUser,
    openAddAssignUser,
    addUserDialogVisible,
    closeAddUser,
    onAddUserOk,
    queryAssignUser,
    requestTreeData: queryOrgList,
    inheritList,
    enableClick,
    disableClick,
    handleNodeClick,
    treeTableRef,
    dialogTitle,
    dialogVisible,
    dialogFormValue,
    editColumn,
    addActionClick,
    editColumnClick,
    selectedValue,
    assignRolesPageInfo,
    orgCode,
    dialogMode,
    deleteRoleData,
    defaultExpandedKeys,
    searchData,
    assignDialogRef,
  };
}
